//
//  Render.m
//  whfdemo002
//
//  Created by 王洪飞 on 2024/6/12.
//

#import "Render.h"
#import "GLProgram.h"

@interface Render ()
{
    GLProgram *programObj;
    GLuint vaoId;
}
@end

@implementation Render

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self prepareData];
        [self setupProgram];
//        [self prepareData1];
//        [self setupProgram1];
    }
    return self;
}

-(void)prepareData{
    GLfloat vertices[20] = {
//        0.5,0.5,0.0,
//        -0.5,0.5,0.0,
//        0.5,-0.5,0.0,
//        -0.5,-0.5,0.0,
        0.5,0.5,0.0,            1.0, 0.0,
        -0.5,0.5,0.0,            0.0, 0.0,
        0.5,-0.5,0.0,            1.0, 1.0,
        -0.5,-0.5,0.0,           0.0, 1.0,
    };
    
    GLuint indices[6] = {
        0,1,2,1,2,3
    };
    
    glGenVertexArrays(1, &vaoId);
   
    GLuint vboid, eleId;
    glGenBuffers(1, &vboid);
    
    glBindVertexArray(vaoId);
    glBindBuffer(GL_ARRAY_BUFFER, vboid);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    glGenBuffers(1, &eleId);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eleId);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
    GLuint vpos = [programObj attributeIndex:@"vPos"]; //glGetAttribLocation(program, "vPos");
    glVertexAttribPointer(vpos, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, 0);
    glEnableVertexAttribArray(vpos);
    
    GLuint vCoord = [programObj attributeIndex:@"vCoord"];
    glVertexAttribPointer(vCoord, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3);
    glEnableVertexAttribArray(vCoord);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
  
    glBindVertexArray(0);
}


-(void)prepareData1{
    GLfloat vertices[20] = {
//        0.5,0.5,0.0,
//        -0.5,0.5,0.0,
//        0.5,-0.5,0.0,
//        -0.5,-0.5,0.0,
        0.5,0.5,0.0,            1.0, 0.0,
        -0.5,0.5,0.0,            0.0, 0.0,
        0.5,-0.5,0.0,            1.0, 1.0,
        -0.5,-0.5,0.0,           0.0, 1.0,
    };
    
    GLuint indices[6] = {
        0,1,2,1,2,3
    };
    
    glGenVertexArrays(1, &vaoId);
   
    GLuint vboid, eleId;
    glGenBuffers(1, &vboid);
    
    glBindVertexArray(vaoId);
    glBindBuffer(GL_ARRAY_BUFFER, vboid);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    glGenBuffers(1, &eleId);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eleId);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
   // GLuint vpos = [programObj attributeIndex:@"vPos"]; //glGetAttribLocation(program, "vPos");
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, 0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3);
    glEnableVertexAttribArray(1);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
  
    glBindVertexArray(0);
}

-(void)setupProgram1{
    char vShaderStr[] =
       "#version 300 es                          \n"
       "layout(location = 0) in vec3 vPosition;  \n"
       "layout(location = 1) in vec2 vCoord;  \n"
       "void main()                              \n"
       "{                                        \n"
       "   gl_Position = vec4(vPosition, 1.0);              \n"
       "}                                        \n";

    char fShaderStr[] =
       "#version 300 es                              \n"
       "precision mediump float;                     \n"
       "out vec4 fragColor;                          \n"
       "void main()                                  \n"
       "{                                            \n"
       "   fragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );  \n"
       "}                                            \n";
    programObj = [[GLProgram alloc] initWithVertexShaderString:[NSString stringWithFormat:@"%s", vShaderStr] fragmentShaderString:[NSString stringWithFormat:@"%s",fShaderStr]];
    if([programObj link]){
        [programObj use];
    }
}

-(void)setupProgram{
    NSString *vShaderStr = @""
    "attribute vec3 vPos;\n"
    "attribute vec2 vCoord;\n"
    "varying vec2 coord;\n"
    "void main(){gl_Position = vec4(vPos,1.0);"
    "coord = vCoord;}";
    NSString *fShaderStr = @""
    "precision mediump float;"
    "varying vec2 coord;\n"
    "uniform sampler2D s_texture;\n"
    "void main(){gl_FragColor = vec4(coord.x,coord.y,1,1);}";
    programObj = [[GLProgram alloc] initWithVertexShaderString:vShaderStr fragmentShaderString:fShaderStr];
    if([programObj link]){
        [programObj use];
        [programObj addAttribute:@"vPos"];
        [programObj addAttribute:@"vCoord"];
    }
}

-(void)draw{
    glBindVertexArray(vaoId);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
}

@end
